package com.neuralnoise;

import java.util.Collection;
import java.util.LinkedList;
import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.Criteria;
import org.hibernate.criterion.Restrictions;

import com.google.code.linkedinapi.schema.Person;
import com.neuralnoise.hibernate.HibernateSessionFactory;
import com.neuralnoise.hibernate.linkedin.Profile;
import com.neuralnoise.hibernate.linkedin.ProfileDAO;
import com.neuralnoise.hibernate.linkedin.User;
import com.neuralnoise.hibernate.linkedin.UserDAO;

public class LinkedInDB extends AbstractDB {

	private Logger logger = Logger.getLogger(this.getClass());
	
	private LinkedInDB() { }
	
	public static void clean() {
		HibernateSessionFactory.getSession().beginTransaction();
		UserDAO udao = new UserDAO();
		List<User> users = udao.findAll();
		for (User user : users) {
			udao.delete(user);
		}
		HibernateSessionFactory.getSession().getTransaction().commit();
	}

	public static User getUser(String id) {
		HibernateSessionFactory.getSession().beginTransaction();
		UserDAO jdao = new UserDAO();
		User User = jdao.findById(id);
		HibernateSessionFactory.getSession().getTransaction().commit();
		return User;
	}
	
	public static Collection<User> getUsers() {
		HibernateSessionFactory.getSession().beginTransaction();
		UserDAO jdao = new UserDAO();
		List<User> Users = jdao.findAll();
		HibernateSessionFactory.getSession().getTransaction().commit();
		return Users;
	}
	
	public static User addUser(String id) {
		HibernateSessionFactory.getSession().beginTransaction();
		UserDAO jdao = new UserDAO();
		User User = new User(id);
		jdao.merge(User);
		HibernateSessionFactory.getSession().getTransaction().commit();
		return User;
	}
	
	public static void delUser(String id) {
		HibernateSessionFactory.getSession().beginTransaction();
		UserDAO jdao = new UserDAO();
		User j = jdao.findById(id);
		if (j != null) {
			jdao.delete(j);
		}
		HibernateSessionFactory.getSession().getTransaction().commit();
	}
	
	public static User toUser(String name) {
		HibernateSessionFactory.getSession().beginTransaction();
		UserDAO jdao = new UserDAO();
		User User = jdao.findById(name);
		if (User == null) {
			User = new User(name);
			jdao.merge(User);
		}
		HibernateSessionFactory.getSession().getTransaction().commit();
		return User;
	}
	
	public static Profile getProfile(String user) {
		HibernateSessionFactory.getSession().beginTransaction();
		ProfileDAO pdao = new ProfileDAO();
		Profile profile = pdao.findById(user);
		HibernateSessionFactory.getSession().getTransaction().commit();
		return profile;
	}
	
	public static Collection<Profile> getProfiles() {
		HibernateSessionFactory.getSession().beginTransaction();
		ProfileDAO pdao = new ProfileDAO();
		Collection<Profile> profiles = pdao.findAll();
		HibernateSessionFactory.getSession().getTransaction().commit();
		return profiles;
	}
	
	// XXX
	public static void addProfile(String user, Person person) {
		HibernateSessionFactory.getSession().beginTransaction();
		ProfileDAO pdao = new ProfileDAO();
		final String location = (person.getLocation() != null ? person.getLocation().getName() : null);
		Profile p = new Profile(user, person.getFirstName(), person.getLastName(), location);
		pdao.merge(p);
		HibernateSessionFactory.getSession().getTransaction().commit();
	}
	
	public static void addProfile(String user, String firstName, String lastName, String location) {
		HibernateSessionFactory.getSession().beginTransaction();
		ProfileDAO pdao = new ProfileDAO();
		Profile p = new Profile(user, firstName, lastName, location);
		pdao.merge(p);
		HibernateSessionFactory.getSession().getTransaction().commit();
	}
	
	public static Collection<User> getFriendsOf(String id) {
		HibernateSessionFactory.getSession().beginTransaction();
		Criteria criteria = HibernateSessionFactory.getSession().createCriteria(User.class);
		criteria = criteria.createAlias("usersForSubject", "friendsOf");
		criteria = criteria.add(Restrictions.eq("friendsOf.id", id));
		Collection<User> friends = criteria.list();
		HibernateSessionFactory.getSession().getTransaction().commit();
		return friends;
	}
	
	public static Collection<User> addFriendsOf(String id, Collection<String> friends) {
		User User = toUser(id);
		Collection<User> ufriends = new LinkedList<User>();
		for (String friend : friends) {
			ufriends.add(toUser(friend));
		}
		HibernateSessionFactory.getSession().beginTransaction();
		UserDAO udao = new UserDAO();
		for (User jfriend : ufriends) {
			User.getUsersForObject().add(jfriend);
			udao.merge(User);
		}
		HibernateSessionFactory.getSession().getTransaction().commit();
		return ufriends;
	}
	
	public static User addFriendOf(String id, String friend) {
		User User = toUser(id);
		User ufriend = toUser(friend);
		HibernateSessionFactory.getSession().beginTransaction();
		UserDAO udao = new UserDAO();
		User.getUsersForObject().add(ufriend);
		udao.merge(User);
		HibernateSessionFactory.getSession().getTransaction().commit();
		return ufriend;
	}
}
